"""
线性回归可视化模块
"""
import matplotlib

matplotlib.use('Agg')
matplotlib.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'Arial Unicode MS']
matplotlib.rcParams['axes.unicode_minus'] = False
import numpy as np
import matplotlib.pyplot as plt
import io
import base64
from matplotlib.font_manager import FontProperties
import platform


# 根据操作系统设置中文字体
def get_chinese_font():
    system = platform.system()
    if system == 'Windows':
        font_path = 'C:/Windows/Fonts/simhei.ttf'
    elif system == 'Darwin':
        font_path = '/System/Library/Fonts/PingFang.ttc'
    else:
        font_path = '/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc'
    return FontProperties(fname=font_path)


chinese_font = get_chinese_font()


def generate_linear_regression_visualizations(y_test: np.ndarray, y_pred: np.ndarray) -> dict:
    """
    生成线性回归的所有可视化图表
    
    Args:
        y_test: 测试集实际值
        y_pred: 测试集预测值
        
    Returns:
        dict: 包含所有可视化图表的base64字符串
    """
    visualizations = {}

    # 1. 散点图：实际值 vs 预测值
    visualizations['scatter'] = _generate_scatter_plot(y_test, y_pred)

    # 2. 残差图
    visualizations['residual'] = _generate_residual_plot(y_pred, y_test)

    return visualizations


def _generate_scatter_plot(y_test: np.ndarray, y_pred: np.ndarray) -> str:
    """生成散点图：实际值 vs 预测值"""
    plt.figure(figsize=(8, 6))
    plt.scatter(y_test, y_pred, alpha=0.5)
    plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
    plt.xlabel('实际值', fontsize=12, fontproperties=chinese_font)
    plt.ylabel('预测值', fontsize=12, fontproperties=chinese_font)
    plt.title('线性回归：实际值 vs 预测值', fontsize=14, fontproperties=chinese_font)

    # 设置坐标轴刻度字体
    plt.xticks(fontproperties=chinese_font)
    plt.yticks(fontproperties=chinese_font)

    return _save_figure_to_base64()


def _generate_residual_plot(y_pred: np.ndarray, y_test: np.ndarray) -> str:
    """生成残差图"""
    plt.figure(figsize=(8, 6))
    residuals = y_test - y_pred
    plt.scatter(y_pred, residuals, alpha=0.5)
    plt.axhline(0, color='red', linestyle='--')
    plt.xlabel('预测值', fontsize=12, fontproperties=chinese_font)
    plt.ylabel('残差', fontsize=12, fontproperties=chinese_font)
    plt.title('线性回归：残差图', fontsize=14, fontproperties=chinese_font)

    # 设置坐标轴刻度字体
    plt.xticks(fontproperties=chinese_font)
    plt.yticks(fontproperties=chinese_font)

    return _save_figure_to_base64()


def _save_figure_to_base64() -> str:
    """将当前图形保存为base64字符串"""
    buf = io.BytesIO()
    plt.savefig(buf, format='png', bbox_inches='tight', dpi=300)
    plt.close()
    buf.seek(0)
    return base64.b64encode(buf.read()).decode()
